class ExcelExporter {
    /**
     * 构造函数
     * @param {Object} options 配置项
     * @param {Array} options.tableData 表格数据
     * @param {Array} options.tableColumns 表头配置
     * @param {String} options.sheetName 工作表名称
     * @param {Number} options.freezeCols 冻结的列数
     * @param {Number} options.freezeRows 冻结的行数
     * @param {String} options.fileName 导出文件名
     */
    constructor(options = {}) {
        this.tableData = options.tableData || [];
        this.tableColumns = options.tableColumns || [];
        this.sheetName = options.sheetName || '工作表';
        this.freezeCols = options.freezeCols || 6;
        this.freezeRows = options.freezeRows || 3;
        this.fileName = options.fileName || '导出数据.xlsx';
        this.productionLine =  options.productionLine || []; // 生产线需要判断数据
        this.materialsList = options.materialsList || [] //物料情况
        // 初始化颜色配置
        this.bgColor = {
            1: { fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF81B5E8' } }, font: { color: { argb: 'FF333333' } } },
            2: { fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF00CED1' } }, font: { color: { argb: 'FF333333' } } },
            3: { fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFFFFFFF' } }, font: { color: { argb: 'FF333333' } } },
            4: { fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFE53935' } }, font: { color: { argb: 'FFFFFFFF' } } },
            5: { fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFC62828' } }, font: { color: { argb: 'FFFFFFFF' } } },
            6: { fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFFFFFFF' } }, font: { color: { argb: 'FF333333' } } },
        };
    }

    /**
     * 递归解析表头（只处理叶子节点的prop）
     * @param {Array} columns 表头列配置
     * @param {Number} currentLevel 当前层级
     * @param {Object} context 上下文（存储列索引和合并规则）
     */
    parseColumns(columns, currentLevel, context) {
        columns.forEach(column => {
            const startCol = context.currentColIndex;
            let endCol;

            // 有子节点：递归处理，自身是非叶子节点（不存储prop）
            if (column.children && column.children.length > 0) {
                this.parseColumns(column.children, currentLevel + 1, context);
                endCol = context.currentColIndex - 1;
            }
            // 无子节点：叶子节点（可能有prop）
            else {
                endCol = context.currentColIndex;
                context.currentColIndex++;
            }

            // 固定列判断（前6列且为叶子节点）
            const isFixedColumn = startCol <= 6 && !column.children;

            context.mergeRules.push({
                startRow: currentLevel,
                endRow: isFixedColumn ? context.maxLevel : currentLevel,
                startCol,
                endCol,
                label: column.label,
                width: column.width || 120,
                isFixed: isFixedColumn,
                isLeaf:  column.children && column.children.length ? false :  true,  // 标记是否为叶子节点
                prop: column.prop  // 只在叶子节点有值
            });
        });
    }

    /**
     * 提取所有叶子节点的prop（按表头顺序）
     * @param {Array} mergeRules 合并规则
     * @returns {Array} 叶子节点的prop数组
     */
    getLeafProps(mergeRules) {
        return mergeRules
            .filter(rule => rule.isLeaf)  // 只保留叶子节点
            .map(rule => rule.prop);      // 提取prop
    }

    /**
     * 检查合并冲突
     */
    isMergeConflicting(existingMerges, newMerge) {
        return existingMerges.some(merge => {
            const rowsOverlap = !(newMerge.endRow < merge.startRow || newMerge.startRow > merge.endRow);
            const colsOverlap = !(newMerge.endCol < merge.startCol || newMerge.startCol > merge.endCol);
            return rowsOverlap && colsOverlap;
        });
    }

    /**
     * 填充表头并合并
     */
    fillHeaderAndMerge(worksheet, mergeRules, maxLevel) {
        const appliedMerges = [];

        // 填充表头内容
        mergeRules.forEach(rule => {
            const cell = worksheet.getCell(rule.startRow, rule.startCol);
            cell.value = rule.label;
        });

        // 按层级从高到低合并（避免冲突）
        const sortedRules = [...mergeRules].sort((a, b) => b.startRow - a.startRow);
        sortedRules.forEach(rule => {
            if (!this.isMergeConflicting(appliedMerges, rule)) {
                try {
                    worksheet.mergeCells(rule.startRow, rule.startCol, rule.endRow, rule.endCol);
                    appliedMerges.push(rule);
                } catch (error) {
                    console.warn(`跳过合并冲突: 行${rule.startRow}-${rule.endRow}, 列${rule.startCol}-${rule.endCol}`);
                }
            }
        });

        // 设置列宽
        mergeRules.forEach(rule => {
            if (!worksheet.getColumn(rule.startCol).width) {
                worksheet.getColumn(rule.startCol).width = rule.width / 7;
            }
        });

        // 设置表头样式
        const headerStyle = {
            font: { bold: true, size: 11 },
            alignment: { vertical: 'middle', horizontal: 'center', wrapText: true },
            border: { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } },
            fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFFFFF00' } },
        };

        for (let row = 1; row <= maxLevel; row++) {
            const headerRow = worksheet.getRow(row);
            headerRow.height = 30;
            headerRow.eachCell(cell => { cell.style = headerStyle; });
        }
    }

    /**
     * 填充表格数据（只使用叶子节点的prop）
     */
    fillTableData(worksheet, data, startRow) {
        const dataStyle = {
            alignment: { vertical: 'middle', horizontal: 'center', wrapText: true },
            border: { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } },
        };

        data.forEach((rowData, rowIndex) => {
            const row = worksheet.getRow(startRow + rowIndex);
            row.height = 40;
            rowData.forEach((cellValue, colIndex) => {
                const cell = row.getCell(colIndex + 1);
                cell.value = cellValue;
                cell.style = dataStyle;

                if (colIndex > 5) {
                    cell.style = { ...dataStyle };
                    let num = rowIndex % 3;

                    let dcTime = '';
                    let xqTime = '';
                    let supplier = '';
                    switch (num) {
                        case 0:
                            dcTime = data[rowIndex]?.[colIndex] || '';
                            xqTime = data[rowIndex + 2]?.[colIndex] || '';
                            supplier = data[rowIndex + 1]?.[colIndex] || '';
                            break;
                        case 1:
                            dcTime = data[rowIndex - 1]?.[colIndex] || '';
                            xqTime = data[rowIndex + 1]?.[colIndex] || '';
                            supplier = data[rowIndex]?.[colIndex] || '';
                            break;
                        case 2:
                            dcTime = data[rowIndex - 2]?.[colIndex] || '';
                            xqTime = data[rowIndex]?.[colIndex] || '';
                            supplier = data[rowIndex - 1]?.[colIndex] || '';
                            break;
                    }

                    if (xqTime !== '自制') {
                        if (xqTime && dcTime && this.compareDateTime(dcTime, xqTime)) {
                            cell.style = { ...dataStyle, ...this.bgColor[5] };  // 逾期
                        } else if (xqTime) {
                            if (!supplier) {
                                cell.style = { ...dataStyle, ...this.bgColor[1] }; // 待选择
                            } else if (!dcTime) {
                                cell.style = { ...dataStyle, ...this.bgColor[2] }; // 待确定
                            } else if (xqTime && dcTime) {
                                cell.style = { ...dataStyle, ...this.bgColor[6] }; // 已完成
                            }
                        }
                    }
                }else{
                    cell.style = { ...dataStyle, fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFFFFF00' } }, };
                }
                // 【关键调整】行高逻辑从 cell 循环提到 row 循环判断
                // 这里只做标记，不直接改 row.height

            });
            // 【核心修复】在 row 循环层级，根据标记设置最终行高
            if (rowIndex % 3 === 1) {
                row.height = 80; // 用自定义标记记录特殊行高需求
            }
        });
        // 固定列合并（前6列每3行合并）
        const fixedColumns = [1, 2, 3, 4, 5];
        const mergeGroupSize = 3;
        for (let i = 0; i < data.length; i += mergeGroupSize) {
            const startRowIndex = startRow + i;
            const endRowIndex = startRow + i + mergeGroupSize - 1;
            const actualEndRow = Math.min(endRowIndex, startRow + data.length - 1);
            fixedColumns.forEach(colIndex => {
                try {
                    worksheet.mergeCells(startRowIndex, colIndex, actualEndRow, colIndex);
                } catch (error) {
                    console.warn(`合并失败: 行${startRowIndex}-${actualEndRow} 列${colIndex}`, error);
                }
            });
        }
    }

    /**
     * 比较日期时间
     */
    compareDateTime(time1, time2) {
        const t1 = new Date(time1).getTime();
        const t2 = new Date(time2).getTime();
        return t1 > t2;
    }

    /**
     * 格式化数据：只使用叶子节点的prop（按表头顺序）
     */
    formatTableDataForExcel() {
        // 1. 先解析表头，获取所有叶子节点的prop（按顺序）
        const tempContext = { currentColIndex: 1, mergeRules: [], maxLevel: 3 };
        this.parseColumns(this.tableColumns, 1, tempContext);
        const leafProps = this.getLeafProps(tempContext.mergeRules);
        // 2. 按叶子节点prop顺序映射数据
        return this.tableData.map((rowObj, rowIndex) => {
            return leafProps.map(prop => {
                // 序号列特殊处理（type: 'index'）

                let idx = 3 * (Math.floor(rowIndex / 3) + 1) - 1  // 获取需求字段下标

                if (prop === 'index' && this.tableColumns[0]?.type === 'index' && leafProps.indexOf(prop) === 0) {
                    return Math.floor(rowIndex / 3) + 1;
                }
                if(prop === 'productionLine') return this.selectDictLabel(this.productionLine,rowObj[prop]);
                if(prop === 'dataType') return this.selectDictLabel(this.materialsList,rowObj[prop]);
                if(this.tableData[idx][prop] === '自制') return rowObj[prop] || '/'
                // 其他列直接取prop对应的值
                return rowObj[prop] || '';
            });
        });
    }
    /**
     * 字符串大小写转换
     */
    convertCase(str, type) {
        // 检查输入是否为字符串
        if (typeof str !== 'string') {
            throw new Error('第一个参数必须是字符串');
        }

        // 转换类型处理
        const convertType = type.toLowerCase();

        // 转换为大写
        if (convertType === 'upper') {
            return str.toUpperCase();
        }
        // 转换为小写
        else if (convertType === 'lower') {
            return str.toLowerCase();
        }
        // 无效的转换类型
        else {
            throw new Error('第二个参数必须是 "upper" 或 "lower"');
        }
    }


    selectDictLabel(data, value, dictLabel = 'dictLabel', dictValue = 'dictValue') {
        // 数据为空时直接返回原始值
        if (!data || data.length === 0) return value || '';

        // 查找匹配项（使用严格相等 ===）
        const item = data.find(item => item[dictValue] == value);

        // 找到返回标签，未找到返回原始值
        return item ? item[dictLabel] : value || '';
    }
    /**
     * 生成Excel并下载
     * @returns {Promise}
     */
    async export() {
        try {
            if (typeof ExcelJS === 'undefined') {
                throw new Error('请先引入ExcelJS库');
            }
            if (typeof saveAs === 'undefined') {
                throw new Error('请先引入FileSaver库');
            }

            const workbook = new ExcelJS.Workbook();
            const worksheet = workbook.addWorksheet(this.sheetName);

            // 设置冻结窗格
            worksheet.views = [{
                state: 'frozen',
                xSplit: this.freezeCols,
                ySplit: this.freezeRows
            }];

            const maxLevel = 3;
            const context = { currentColIndex: 1, mergeRules: [], maxLevel };

            // 解析表头（包含叶子节点标记）
            this.parseColumns(this.tableColumns, 1, context);

            

            // 填充表头
            this.fillHeaderAndMerge(worksheet, context.mergeRules, maxLevel);

            // 格式化并填充数据（只使用叶子节点的prop）
            const excelData = this.formatTableDataForExcel();
            this.fillTableData(worksheet, excelData, maxLevel + 1);

            // 下载文件
            const buffer = await workbook.xlsx.writeBuffer();
            const blob = new Blob([buffer], {
                type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
            });
            saveAs(blob, this.fileName);

            return { success: true };
        } catch (error) {
            console.error('导出失败:', error);
            return {
                success: false,
                message: error.message
            };
        }
    }
}
